﻿/**
 * Created in 2012-3-29.
 */
package kit4j.view.cs.awt.image.drawer;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;

import kit4j.common.image.Polyline;
import kit4j.generator.keyed.IKeyedGenerator;
import kit4j.generator.keyed.RandomAdjacentPointKeyedGenerator;
import kit4j.generator.keyed.RandomPositiveIntegerKeyedGenerator;
import kit4j.generator.keyless.IKeylessGenerator;
import kit4j.generator.keyless.RandomColorKeylessGenerator;

/**
 * 在图像上绘制随机颜色、随机位置的连接线的绘制器。该绘制器确定在图像的每一块指定宽高范围内只存在一条连接线。
 * 
 * @author MiniKnife
 * 
 */
public class RandomColorPolylineDrawer implements IDrawer {

	/**
	 * 每一条连接线所占据区域的宽度。
	 */
	protected int everyLineAreaWidth;

	/**
	 * 每一条连接线所占据区域的高度。
	 */
	protected int everyLineAreaHeight;

	/**
	 * 每一条连接线所包含的点的数量。
	 */
	protected int everyLinePointCount;

	protected IKeyedGenerator<Integer, Integer> intGenerator;
	
	protected IKeylessGenerator<Color> colorGenerator; 

	protected IKeyedGenerator<Point, Point> pointGenerator;

	/**
	 * 创建一个随机连接线绘制器。每一条连接线所占据区域的宽度默认为20，高度为20，每一条连接线所包含的点的数量为25。
	 */
	public RandomColorPolylineDrawer() {
		this(20, 20, 25);
	}

	/**
	 * 创建一个随机连接线绘制器。
	 * 
	 * @param everyLineAreaWidth
	 *            每一条连接线所占据区域的宽度
	 * @param everyLineAreaHeight
	 *            每一条连接线所占据区域的高度
	 * @param everyLinePointCount
	 *            每一条连接线所包含的点的数量
	 */
	public RandomColorPolylineDrawer(int everyLineAreaWidth,
			int everyLineAreaHeight, int everyLinePointCount) {
		this.everyLineAreaWidth = everyLineAreaWidth;
		this.everyLineAreaHeight = everyLineAreaHeight;
		this.everyLinePointCount = everyLinePointCount;

		intGenerator = new RandomPositiveIntegerKeyedGenerator();
		colorGenerator = new RandomColorKeylessGenerator();
		pointGenerator = new RandomAdjacentPointKeyedGenerator();
	}

	/**
	 * @see kit4j.view.cs.awt.image.drawer.IDrawer#draw(java.awt.Image)
	 */
	@Override
	public Image draw(Image img) {
		System.out.println("draw:img=" + img);

		Graphics g = img.getGraphics();
		int imgWidth = img.getWidth(null), imgHeight = img.getHeight(null);

		Polyline line;
		for (int x = 0; x < imgWidth; x += everyLineAreaWidth) {
			for (int y = 0; y < imgHeight; y += everyLineAreaHeight) {
				line = nextPolyline(x, y);

				g.setColor(nextColor());
				g.drawPolyline(line.getXPoints(), line.getYPoints(),
						getEveryLinePointCount());
			}
		}

		return img;
	}
	
	/**
	 * @return 返回下一个要绘制的连接线的颜色。
	 */
	protected Color nextColor() {
		return colorGenerator.next();
	}

	/**
	 * 根据原点坐标生成下一条随机连接线。
	 * 
	 * @param originX
	 *            原点X坐标
	 * @param originY
	 *            原点Y坐标
	 * @return 随机生成的连接线
	 */
	protected Polyline nextPolyline(int originX, int originY) {
		System.out.println("nextPolyline: originX=" + originX + ",originY"
				+ originY);

		return new Polyline(getPoints(originX, originY));
	}

	/**
	 * 根据原点坐标生成一系列随机点。
	 * 
	 * @param originX
	 *            原点X坐标
	 * @param originY
	 *            原点Y坐标
	 * @return 随机生成的点
	 */
	protected Point[] getPoints(int originX, int originY) {
		System.out.println("getPoints: originX=" + originX + ",originY="
				+ originY);

		Point[] points = new Point[everyLinePointCount];

		points[0] = getFirstPoint(originX, originY);
		for (int i = 1; i < everyLinePointCount; ++i) {
			points[i] = pointGenerator.next(points[i - 1]);
		}

		return points;
	}

	/**
	 * 根据原点坐标生成下一个随机起始点。
	 * 
	 * @param originX
	 *            原点X坐标
	 * @param originY
	 *            原点Y坐标
	 * @return 下一个随机起始点
	 */
	protected Point getFirstPoint(int originX, int originY) {
		System.out.println("getFirstPoint: originX=" + originX + ",originY="
				+ originY);

		int x = originX + intGenerator.next(everyLineAreaWidth + 1);
		int y = originY + intGenerator.next(everyLineAreaHeight + 1);

		System.err.println("firstPoint: x=" + x + ",y=" + y);

		return new Point(x, y);
	}

	/**
	 * @return 每一条连接线所占据区域的宽度
	 */
	public int getEveryLineAreaWidth() {
		return everyLineAreaWidth;
	}

	/**
	 * 设置每一条连接线所占据区域的宽度。
	 * 
	 * @param everyLineAreaWidth
	 *            宽度
	 */
	public void setEveryLineAreaWidth(int everyLineAreaWidth) {
		this.everyLineAreaWidth = everyLineAreaWidth;
	}

	/**
	 * @return 每一条连接线所占据区域的高度
	 */
	public int getEveryLineAreaHeight() {
		return everyLineAreaHeight;
	}

	/**
	 * 设置每一条连接线所占据区域的高度。
	 * 
	 * @param everyLineAreaHeight
	 *            高度
	 */
	public void setEveryLineAreaHeight(int everyLineAreaHeight) {
		this.everyLineAreaHeight = everyLineAreaHeight;
	}

	/**
	 * @return 每一条连接线所包含的点的数量
	 */
	public int getEveryLinePointCount() {
		return everyLinePointCount;
	}

	/**
	 * 设置每一条连接线所包含的点的数量。
	 * 
	 * @param everyLinePointCount
	 *            每一条连接线所包含的点的数量
	 */
	public void setEveryLinePointCount(int everyLinePointCount) {
		this.everyLinePointCount = everyLinePointCount;
	}

}
